package neu.soft.service.impl;

import com.alibaba.fastjson.JSON;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import neu.soft.constant.InvoiceType;
import neu.soft.entity.DO.City;
import neu.soft.entity.Invoice;
import neu.soft.entity.InvoiceGoodInfo;
import neu.soft.exception.AppException;
import neu.soft.exception.AppExceptionCodeMsg;
import neu.soft.feignclient.OperationServerFeignClient;
import neu.soft.mapper.InvoiceMapper;
import neu.soft.query.BasePageQuery;
import neu.soft.service.InvoiceService;
import neu.soft.util.InvoiceMockFactory;
import neu.soft.util.RegionCodeUtil;
import neu.soft.util.SnowflakeIdWorker;
import neu.soft.util.TypeConvert;
import neu.soft.vo.PageBean;
import neu.soft.vo.ResultBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

@Service
@Slf4j
public class InvoiceServiceImpl implements InvoiceService {

    @Autowired
    private InvoiceMapper invoiceMapper;

    @Autowired
    OperationServerFeignClient regionFeignClient;

    private static final ThreadLocal<DateFormat> threadLocal = ThreadLocal.withInitial(() -> new SimpleDateFormat("yyyy-MM-dd"));

    @Override
    public Long addInvoice(Invoice invoice) {
        int res = invoiceMapper.addInvoice(invoice);
        if (res < 1) {
            throw new AppException(AppExceptionCodeMsg.DZYJ_NGDZ);
        }
        return invoice.getInvoiceId();
    }

    @Override
    public PageBean<Invoice> findByPage(BasePageQuery basePageQuery) {
        PageBean<Invoice> pageBean = new PageBean<>();
        PageHelper.startPage(basePageQuery.getPageNow(), basePageQuery.getPageSize());
        List<Invoice> invoiceList = invoiceMapper.findByPage(basePageQuery);
        invoiceList.forEach(invoice -> {
            String type = TypeConvert.enumToString(InvoiceType.class,invoice.getInvoiceType());
            invoice.setInvoiceType(type);
        });
        PageInfo<Invoice> pageInfo = new PageInfo<>(invoiceList);
        pageBean.setTotalRows(pageInfo.getTotal());
        pageBean.setTotalPages(pageInfo.getPages());
        pageBean.setRowData(pageInfo.getList());
        return pageBean;
    }

    @Override
    public Invoice findById(Long invoiceId) {

        if (invoiceId == null) {
            throw new AppException(AppExceptionCodeMsg.REQUEST_PARAM_EMPTY);
        }
        return invoiceMapper.findById(invoiceId);
    }

    @Override
    public void batchInsertGoodInfo(List<InvoiceGoodInfo> invoiceGoodInfoList) {

        invoiceMapper.batchInsertGoodInfo(invoiceGoodInfoList);

    }

    //map里包含loc地址信息、batch批次信息，orderId，发票绑定的单号，以及发票类的属性
    @SneakyThrows
    @Override
    public Invoice buildInvoice(Map<String, Object> map) {
        String loc = (String) map.get("loc");//地址信息
        Map<String, String> resMap = RegionCodeUtil.splitLoc(loc);
        String cityName = resMap.get("cityName");//城市名字
        String provinceName = resMap.get("provinceName");//省名字
        String batch = (String) map.get("batch");//批次
        Map<String, Object> objectMap = map.entrySet().stream().filter(entry ->
                (!"loc".equals(entry.getKey()) && !"batch".equals(entry.getKey()) && !"orderId".equals(entry.getKey())
                )).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));//筛选信息到新的Map
        Date date = new Date();//开票日期创建
        String dateStr = threadLocal.get().format(date);
        Date dateRes = threadLocal.get().parse(dateStr);//格式化date
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(dateRes);
        String year = String.valueOf(calendar.get(Calendar.YEAR) - 2000);//得到年度，这里-2000
        objectMap.put("createDate", dateRes);
        Map<String, Object> cityMap = new HashMap<>();
        if ("省直辖行政单位".equals(cityName)) {
            cityMap.put("cityName", provinceName + cityName);//根据数据库数据判断城市名称，使其有辨识度
        } else {
            cityMap.put("cityName", cityName);
        }
        cityMap.put("provinceName", provinceName);//put省名字
        ResultBean<City> cityRes = regionFeignClient.getInfo(cityMap);//调用业务中心接口服务，查询发票号码中的行政代码
        int cityTemp = cityRes.getData().getCityId() / 100;
        String cityId = Integer.toString(cityTemp);//取前四位
        Map<String, String> invoiceCodes = InvoiceMockFactory.builder(cityName, cityId, batch, year, "11");//生成发票号码，代码和名字
        String invoiceCode = invoiceCodes.get("invoiceCode");
        String invoiceNum = invoiceCodes.get("invoiceNum");
        String invoiceName = invoiceCodes.get("invoiceName");
        SnowflakeIdWorker snowflakeIdWorker = SnowflakeIdWorker.getInstance();
        Long invoiceId = snowflakeIdWorker.nextId();//生成唯一标识的id
        objectMap.put("invoiceId", invoiceId);
        objectMap.put("invoiceCode", invoiceCode);
        objectMap.put("invoiceNum", invoiceNum);
        objectMap.put("invoiceName", invoiceName);
        return JSON.parseObject(JSON.toJSONString(objectMap), Invoice.class);//生成发票对象
    }

    @Override
    public Long findInvoiceByOrderId(String orderId) {
        if (orderId == null || "".equals(orderId)) {
            throw new AppException(AppExceptionCodeMsg.REQUEST_PARAM_EMPTY);
        }
        return invoiceMapper.findInvoiceByOrderId(orderId);
    }

    //绑定发票和订单或应付单
    @Override
    public void insertInfoOrder(Long invoiceId, String orderId) {
        invoiceMapper.insertOrderAndInvoice(invoiceId, orderId);
    }

    @Override
    public boolean findInvoiceOrderId(String orderId) {
        int res = invoiceMapper.findInvoiceOrderId(orderId);
        if (res > 0){
            return true;
        }else {
            return false;
        }
    }

    @Override
    public void updateInvoiceType(Long invoiceId,String type) {
        invoiceMapper.update(invoiceId,type);
    }
}
